﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EditableBusinessObjects.Postsharp.Public;
using System.Runtime.Serialization;
using CyclicReferences.Public;

namespace EditableBusinessObjects.Testing
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class usageTests
    {
        #region setup
        public usageTests()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion
        #endregion

        [TestMethod]
        public void tstCanAcceptEdit()
        {
            Person p = new Person { Name = "Ruurd Boeke" };

            IEditableBusinessObject eB = (IEditableBusinessObject)p;
            eB.BeginEdit();

            p.Name = "Changed";

            eB.EndEdit();

            Assert.IsTrue(p.Name == "Changed");
        }

        [TestMethod]
        public void tstCanCancelEdit()
        {
            Person p = new Person { Name = "Ruurd Boeke" };

            IEditableBusinessObject eB = (IEditableBusinessObject)p;
            eB.BeginEdit();

            p.Name = "Changed";

            eB.CancelEdit();

            Assert.IsTrue(p.Name == "Ruurd Boeke");
        }

        [TestMethod]
        public void tstCanCancelWithRelations()
        {
            Person p = new Person { Name = "Ruurd Boeke" };
            p.Cars = new List<Car>();

            Car car1 = new Car { Make = "Porsche", Owner = p };
            p.Cars.Add(car1);



            IEditableBusinessObject eB = (IEditableBusinessObject)p;
            eB.BeginEdit();

            p.Name = "Changed";

            Car car2 = new Car { Make = "BMW", Owner = p };
            p.Cars.Add(car2);

            Assert.IsTrue(p.Cars.Count == 2);
            eB.CancelEdit();

            Assert.IsTrue(p.Cars.Count == 1);

            
        }

        [TestMethod]
        public void tstSerializationAndDeserialization()
        {
            Person p = new Person { Name = "Ruurd Boeke" };
            ((IEditableBusinessObject)p).SetValueAsOriginal("Name", "original value");
            p.Cars = new List<Car>();

            Car car1 = new Car { Make = "Porsche", Owner = p };
            p.Cars.Add(car1);

            DataContractSerializer s = new DataContractSerializer(p.GetType(), null, int.MaxValue, false, false, new SubstituteDomainDataContractSurrogate());

            string outMessage = s.GetWellFormedToContract(p);

            DataContractSerializer s2 = new DataContractSerializer(p.GetType(), null, int.MaxValue, false, false, new SubstituteDomainDataContractSurrogate());
            Person p2 = (Person) s2.UnwrapFromString(outMessage);

            Assert.IsTrue(p2.Cars.Count == p.Cars.Count);
            Assert.IsTrue(p2.Name == "Ruurd Boeke");
            Assert.IsTrue( (string) ((IEditableBusinessObject)p2).GetOriginalValue("Name") == "original value"); 
        }

    }


}
